package com.njust.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.njust.Util.JwtUtil;
import com.njust.Util.RedisUtil;
import com.njust.constant.Constant;
import com.njust.context.BaseContext;
import com.njust.domain.dto.UserLoginDTO;
import com.njust.domain.dto.UserSignInDTO;
import com.njust.domain.po.User;
import com.njust.domain.vo.UserLoginVO;
import com.njust.domain.vo.UserVO;
import com.njust.exception.*;
import com.njust.mapper.*;
import com.njust.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.util.HashMap;
import java.util.Map;


/**
 * @version 1.0
 * @Author Imak
 * @Date 2024/10/18 14:30
 * @注释
 */
@Service
@Slf4j
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private PersonnelCapabilitieMapper personnelCapabilitieMapper;

    @Autowired
    private SampleRequestMapper sampleRequestMapper;

    @Autowired
    private TestPersonMapper testPersonMapper;

    @Autowired
    private EquipmentProcurementMapper equipmentProcurementMapper;


    /**
     * 用户登录
     * @param userLoginDTO
     * @return
     */
    public UserLoginVO login(UserLoginDTO userLoginDTO) {
        String userName=userLoginDTO.getUserName();
        String uPw=userLoginDTO.getUPw();
        User user=userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getUserName, userName));

        if(user==null){
            throw new AccountNotFoundException("账号不存在");
        }
        //md5加密比对
        uPw= DigestUtils.md5DigestAsHex(uPw.getBytes());
        if(!uPw.equals(user.getUPw())){
            throw new PasswordErrorException("密码错误");
        }
        //账号密码正确 检查该账号登陆状态
        Integer uId=user.getUId();

        //尝试获取该用户id对应的登陆状态 map<username,uId>
//        String uIdStr=redisUtil.getCacheObject(userName);
//        if(uIdStr!=null&&user.getUStatus()!= Constant.ADMIN){//记录不为空 表示该账号已经被登录
//            //阻止登录
//            throw new AccountHasLogin("账号已经在其他设备登录！");
//        }
//        //标记已登录
//        redisUtil.setCacheObject(userName,uId.toString());

        //登录成功后，生成jwt令牌
        String token= JwtUtil.generateJWT(uId);
        UserLoginVO userLoginVO=UserLoginVO.builder()
                .uId(uId)
                .uStatus(user.getUStatus())
                .token(token)
                .build();
        return userLoginVO;
    }
    /**
     * 注销账号
     * @param uId
     * @return
     */
    public void deleteAcc(Integer uId) {
        User user=userMapper.selectById(uId);
        if(user.getUStatus()!=0){
            throw new DeleteAccountFailedException("非检测人员，无法注销账号!");
        }
        //TODO
        //删除前，清除对应人员记录，设备采购表，人员能力表，样品需求表，测试人员表
        QueryWrapper wrapper=new QueryWrapper<>();
        wrapper.eq("uId",uId);
        personnelCapabilitieMapper.delete(wrapper);
        equipmentProcurementMapper.delete(wrapper);
        sampleRequestMapper.delete(wrapper);
        testPersonMapper.delete(wrapper);

        int result = userMapper.deleteById(uId);
        if(result <= 0){
            throw new DeleteAccountFailedException("注销失败");
        }
        redisUtil.deleteObject(user.getUserName());

    }

    /**
     * 退出登录
     * @param uId
     */
    public void logout(Integer uId) {
        //从Redis中删除记录
        User user=userMapper.selectById(uId);
        redisUtil.deleteObject(user.getUserName());
        log.info("删除用户缓存{}",user.getUserName());
    }

    /**
     * 获取用户个人信息
     * @param uId
     * @return
     */
    public UserVO userInfo(Integer uId) {
        User user=userMapper.selectById(uId);
        if(user==null) {
            log.info("该用户不存在,uId={}",uId);
            throw new UserInfoError("用户状态异常，信息获取失败！");

        }
        UserVO userVO=new UserVO();
        BeanUtils.copyProperties(user,userVO);
        return userVO;
    }

    /**
     * 用户注册
     *
     * @param userSignInDTO
     * @return
     */
    @Override
    public User sign(UserSignInDTO userSignInDTO) {
        String userName = userSignInDTO.getUserName();
        String uPw = userSignInDTO.getUPw();
        String uName = userSignInDTO.getUName();
        String institution = userSignInDTO.getInstitution();
        String uTel = userSignInDTO.getUTel();
        if(userName==null||uPw==null||uName==null||institution==null||uTel==null){
            throw new SignInFailure("有未填写字段，注册失败");
        }
        User userChecking = userMapper.selectOne(
                new LambdaQueryWrapper<User>().eq(User::getUserName, userName));
        if (userChecking != null) {
            throw new AccountAlreadyExists("账号已经存在");
        }
        User user = User.builder()
                .userName(userName)
                .uPw(DigestUtils.md5DigestAsHex(uPw.getBytes()))//md5加密存储
                .uName(uName)
                .institution(institution)
                .uTel(uTel)
                .build();
        int code = userMapper.insert(user);
        return user;
    }
}
